/**************************************************************************************************
**                                                                                               **
**  文件名称:  dal_led_man.c                                                                     **
**  版权所有:  CopyRight @ Xiamen Yaxon NetWork CO.LTD. 2017                                     **
**  文件描述:  实现对LED闪灯的管理控制                                                           **
**  ===========================================================================================  **
**  创建信息:  | 2017-3-17 | LEON | 创建本模块                                                   **
**  ===========================================================================================  **
**  修改信息:  单击此处添加....                                                                  **
**************************************************************************************************/
#include "dal_include.h"
#include "dal_led_man.h"

/*************************************************************************************************/
/*                           模块宏定义                                                          */
/*************************************************************************************************/
#define PERIOD_FLASH         _TICK, 10                                         /* 10 ms */

/*************************************************************************************************/
/*                           各种模式下的闪烁状态控制[单位: PERIOD_FLASH]                        */
/*************************************************************************************************/
typedef struct {
    INT8U       ttime_h;                                                       /* 高电平需要持续的时间 */
    INT8U       xtime_h;                                                       /* 高电平已经持续的时间 */
    INT8U       ttime_l;                                                       /* 低电平需要持续的时间 */
    INT8U       xtime_l;                                                       /* 低电平已经持续的时间 */
} FCTRL_T;

/*************************************************************************************************/
/*                           常态模式下的闪烁状态控制[单位: PERIOD_FLASH]                        */
/*************************************************************************************************/
typedef struct {
    FCTRL_T     fl_ctrl;                                                       /* 通用闪烁状态控制结构 */
    INT16U      t_cycle;                                                       /* 常态下需要闪烁的轮数 */
    INT16U      x_cycle;                                                       /* 常态下已经闪烁的轮数 */
    INT8U       ttime_d;                                                       /* 闪烁后需要熄灭的时间 */
    INT8U       xtime_d;                                                       /* 闪烁后已经熄灭的时间 */
} COMM_FC_T;

/*************************************************************************************************/
/*                           暂态模式下的闪烁状态控制[单位: PERIOD_FLASH]                        */
/*************************************************************************************************/
typedef struct {
    FCTRL_T     fl_ctrl;                                                       /* 通用闪烁状态控制结构 */
    INT16U      ttcycle;                                                       /* 暂态下还需闪烁的轮数 */
} TEMP_FC_T;

/*************************************************************************************************/
/*                           LED闪烁统一控制结构                                                 */
/*************************************************************************************************/
typedef struct {
    COMM_FC_T     comm;                                                        /* 常态闪烁控制 */
    TEMP_FC_T     temp;                                                        /* 暂态闪烁控制 */
} LED_FLASH_T;

/*************************************************************************************************/
/*                           模块静态变量定义                                                    */
/*************************************************************************************************/
static INT8U        s_flashtmr;
static LED_FLASH_T  s_ledtfcb[LED_NAME_MAX];

/**************************************************************************************************
**  函数名称:  HdlTempModeFlash
**  功能描述:  处理暂态模式下的闪烁控制
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void HdlTempModeFlash(LED_NAME_E led)
{
    if (s_ledtfcb[led].temp.fl_ctrl.xtime_h > 0) {                             /* 先进行高电平控制 */
        s_ledtfcb[led].temp.fl_ctrl.xtime_h--;
        BSP_LightupLEDPort(led);
    } else {                                                                   /* 再进行低电平控制 */
        if (s_ledtfcb[led].temp.fl_ctrl.xtime_l > 0) {
            s_ledtfcb[led].temp.fl_ctrl.xtime_l--;
            BSP_TurnOFFLEDPort(led);
        } else {                                                               /* 一个周期结束，重新加载 */
            s_ledtfcb[led].temp.fl_ctrl.xtime_h = s_ledtfcb[led].temp.fl_ctrl.ttime_h;
            s_ledtfcb[led].temp.fl_ctrl.xtime_l = s_ledtfcb[led].temp.fl_ctrl.ttime_l;

            if (s_ledtfcb[led].temp.ttcycle > 0) {                             /* 闪烁周期尚未执行完毕 */
                s_ledtfcb[led].temp.ttcycle--;
            }
        }
    }
}

/**************************************************************************************************
**  函数名称:  HdlCommModeFlash
**  功能描述:  处理常态模式下的闪烁控制
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void HdlCommModeFlash(LED_NAME_E led)
{
    if (s_ledtfcb[led].comm.xtime_d > 0) {                                     /* 正处于熄灭状态下 */
        s_ledtfcb[led].comm.xtime_d--;
        return;
    }
    
    if (s_ledtfcb[led].comm.fl_ctrl.xtime_h > 0) {                             /* 先进行闪烁模式下的高电平控制 */
        s_ledtfcb[led].comm.fl_ctrl.xtime_h--;
        BSP_LightupLEDPort(led);
    } else {                                                                   /* 再进行闪烁模式下的低电平控制 */
        if (s_ledtfcb[led].comm.fl_ctrl.xtime_l > 0) {
            s_ledtfcb[led].comm.fl_ctrl.xtime_l--;
            BSP_TurnOFFLEDPort(led);
        } else {                                                               /* 本轮闪烁逻辑执行完毕 */
            if (s_ledtfcb[led].comm.x_cycle > 0) {                             /* 依次执行各轮闪烁逻辑 */
                s_ledtfcb[led].comm.x_cycle--;
                
                s_ledtfcb[led].comm.fl_ctrl.xtime_h = s_ledtfcb[led].comm.fl_ctrl.ttime_h;
                s_ledtfcb[led].comm.fl_ctrl.xtime_l = s_ledtfcb[led].comm.fl_ctrl.ttime_l;
                
            } else {                                                           /* 全部闪烁逻辑执行完毕 */
                s_ledtfcb[led].comm.x_cycle = s_ledtfcb[led].comm.t_cycle;
                s_ledtfcb[led].comm.xtime_d = s_ledtfcb[led].comm.ttime_d;
                BSP_TurnOFFLEDPort(led);                                       /* 进入熄灭状态 */
            }
        }
    }
}

/**************************************************************************************************
**  函数名称:  FlashTmrProc
**  功能描述:  定时执行函数，控制输出口的状态
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
static void FlashTmrProc(void)
{
    LED_NAME_E   i;
        
    for (i = (LED_NAME_E)0; i < LED_NAME_MAX; i++) {                           /* 依次查询每一个LED */
        
        if (s_ledtfcb[i].temp.ttcycle > 0) {                                   /* 暂态闪烁尚未执行完 */
            HdlTempModeFlash(i);
            continue;                                                          /* 暂态闪烁未完成时不处理常态闪烁 */
        }
        
        HdlCommModeFlash(i);                                                   /* 处理常态模式下的闪烁控制 */
    }
}

/**************************************************************************************************
**  函数名称:  DAL_LED_Init
**  功能描述:  初始化管理模块
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_LED_Init(void)
{
    s_flashtmr = OSL_CreateTimer(FlashTmrProc);
    OSL_StartTimer(s_flashtmr, PERIOD_FLASH);
}

/**************************************************************************************************
**  函数名称:  DAL_LED_StartLimitFlash
**  功能描述:  注册一个临时闪烁控制逻辑 (常用于临时状态的指示，闪烁有限的次数后自动停止)
**  输入参数:  name:	输入口类型, 见OUTPUT_IO_E
**             cycle:   次数
**             ttime_h:	高电平持续时间，单位: PERIOD_FLASH
**             ttime_l:	低电平持续时间，单位: PERIOD_FLASH
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_LED_StartLimitFlash(LED_NAME_E name, INT16U cycle, INT8U ttime_h, INT8U ttime_l)
{
    SYS_ASSERT((name < LED_NAME_MAX), RETURN_VOID);
    
    if ((cycle != 0) && ((ttime_h == 0) && (ttime_l == 0))) {
        return;
    }
    
    if (cycle == 0) {
        return;
    }
    
    s_ledtfcb[name].temp.ttcycle = cycle;
    s_ledtfcb[name].temp.fl_ctrl.ttime_h = ttime_h;
    s_ledtfcb[name].temp.fl_ctrl.xtime_h = ttime_h;
    s_ledtfcb[name].temp.fl_ctrl.ttime_l = ttime_l;
    s_ledtfcb[name].temp.fl_ctrl.xtime_l = ttime_l;
}

/**************************************************************************************************
**  函数名称:  DAL_LED_StopLimitFlash
**  功能描述:  停止一个临时闪烁控制逻辑
**  输入参数:  name: 输入口类型, 见OUTPUT_IO_E
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_LED_StopLimitFlash(LED_NAME_E name)
{
    SYS_ASSERT((name < LED_NAME_MAX), RETURN_VOID);
    
    s_ledtfcb[name].temp.ttcycle = 0;
    s_ledtfcb[name].temp.fl_ctrl.ttime_h = 0;
    s_ledtfcb[name].temp.fl_ctrl.xtime_h = 0;
    s_ledtfcb[name].temp.fl_ctrl.ttime_l = 0;
    s_ledtfcb[name].temp.fl_ctrl.xtime_l = 0;
    
    BSP_TurnOFFLEDPort(name);                                                    /* 拉低管脚输出 */
}

/**************************************************************************************************
**  函数名称:  DAL_LED_StartPermentFlash
**  功能描述:  注册一个永久闪烁控制逻辑
**  输入参数:  name:      输入口类型
**  输入参数:  ttime_h:   高电平持续时间, 单位: PERIOD_FLASH
**  输入参数:  ttime_l:   低电平持续时间, 单位: PERIOD_FLASH
**  输入参数:  circle:    闪烁次数。不能为0，最小必须为1
**  输入参数:  dead_time: 熄灭时间, 单位PERIOD_FLASH。可以等于0，等于0则表示不需要熄灭，直接进行下轮闪烁
***************************************************************************************************
**  波形说明:  ┌──┐    ┌──┐                  ┌──┐    ┌──┐
**  波形说明:  │    │    │    │                  │    │    │    │
**  波形说明:  │    └──┘    └─────────┘    └──┘    └──────────
**  波形说明:  │    │    │    │    │            │    │    │    │    │            │
**  波形说明:  │ 高    低    高    低 │ dead_time  │ 高    低    高    低 │ dead_time  │
**  波形说明:  │    cycle (eg: 2)     │ dead_time  │    cycle (eg: 2)     │ dead_time  │
**************************************************************************************************/
void DAL_LED_StartPermentFlash(LED_NAME_E name, INT8U ttime_h, INT8U ttime_l, INT8U cycle, INT8U dead_time)
{
    SYS_ASSERT((name < LED_NAME_MAX), RETURN_VOID);
    
    if (((ttime_h == 0) && (ttime_l == 0)) || (cycle == 0)) {
        return;
    }
    
    s_ledtfcb[name].comm.t_cycle = cycle;
    s_ledtfcb[name].comm.x_cycle = cycle;
    s_ledtfcb[name].comm.ttime_d = dead_time;
    s_ledtfcb[name].comm.xtime_d = 0;
    s_ledtfcb[name].comm.fl_ctrl.ttime_h = ttime_h;
    s_ledtfcb[name].comm.fl_ctrl.xtime_h = ttime_h;
    s_ledtfcb[name].comm.fl_ctrl.ttime_l = ttime_l;
    s_ledtfcb[name].comm.fl_ctrl.xtime_l = ttime_l;
}

/**************************************************************************************************
**  函数名称:  DAL_LED_StopPermentFlash
**  功能描述:  停止一个永久闪烁控制逻辑
**  输入参数:  name: 输入口类型
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void DAL_LED_StopPermentFlash(LED_NAME_E name)
{
    SYS_ASSERT((name < LED_NAME_MAX), RETURN_VOID);
    
    s_ledtfcb[name].comm.t_cycle = 0;
    s_ledtfcb[name].comm.x_cycle = 0;
    s_ledtfcb[name].comm.ttime_d = 0;
    s_ledtfcb[name].comm.xtime_d = 0;
    s_ledtfcb[name].comm.fl_ctrl.ttime_h = 0;
    s_ledtfcb[name].comm.fl_ctrl.xtime_h = 0;
    s_ledtfcb[name].comm.fl_ctrl.ttime_l = 0;
    s_ledtfcb[name].comm.fl_ctrl.xtime_l = 0;
    
    BSP_TurnOFFLEDPort(name);                                                    /* 拉低管脚输出 */
}

 
